
import os
import sys
import cPickle

import rpyc

from dexen.system import constants


class FrontendAPI:
    def __init__(self, url):
        self.conn = rpyc.connect(url, port=constants.FRONTEND_SRVC_PORT,
                                 config={"instantiate_custom_exceptions":True})
    
    def _get_local_copy(self, remote_copy):
        local_copy = []
        for item in remote_copy:
            local_copy.append(item)
        return local_copy
    
    def reset_all_databases(self):
        self.conn.root.reset_all_databases()
                
    def set_schema(self, schema_name, zip_data, last_modified_time):
        self.conn.root.set_schema(schema_name, zip_data, last_modified_time)
      
    def get_schema(self, schema_name):
        return self.conn.root.get_schema(schema_name)
        
    def get_schema_names(self):
         return self._get_local_copy(self.conn.root.get_schema_names())
    
    def get_schema_timestamp(self, schema_name):
        return self.conn.root.get_schema_timestamp(schema_name)
    
    def get_population_creation_time(self, schema_name, pop_name):
        return self.conn.root.get_population_creation_time(schema_name, pop_name)
    
    def set_population(self, schema_name, pop_name, creation_time):
        self.conn.root.set_population(schema_name, pop_name, creation_time)

    def get_population_names(self, schema_name):
        pop_names = self.conn.root.get_population_names(schema_name)
        return self._get_local_copy(pop_names)
    
    def delete_population(self, schema_name, pop_name):
        self.conn.root.delete_population(schema_name, pop_name)
    
    def get_script_names(self, schema_name, pop_name):
        script_names = self.conn.root.get_script_names(schema_name, pop_name)
        return self._get_local_copy(script_names)

    def get_script_run_type(self, schema_name, pop_name, script_name):
        return self.conn.root.get_script_run_type(schema_name, pop_name, 
                                               script_name)

    def get_script_file_function_names(self, schema_name, pop_name, script_name):
        return self._get_local_copy(
                    self.conn.root.get_script_file_function_names(
                        schema_name, pop_name, script_name
                    )
               )    
    
    def set_individual_table(self, schema_name, pop_name):
        self.conn.root.set_individual_table(schema_name, pop_name)   

    def stop_script(self, schema_name, pop_name, script_name):
        print "stop script in frontend_api right before the remote call"
        self.conn.root.stop_script(schema_name, pop_name, script_name)

class LooperAPI:  
    def __init__(self, url, schema_name, pop_name, script_name):
        self.url = url
        self.schema_name = schema_name
        self.pop_name = pop_name
        self.script_name = script_name
        self.conn = rpyc.connect(url, constants.LOOPER_SRVC_PORT, 
                                 config={"instantiate_custom_exceptions":True})
        self.conn.root.initialize(schema_name, pop_name, script_name)
        
    def download_live_individuals(self, at_time=None):
        individuals = self.conn.root.get_live_individuals(at_time)
        return cPickle.loads(individuals)
    
    def download_individuals(self):
        individuals = self.conn.root.get_individuals()
        return cPickle.loads(individuals)

    def upload_individuals(self, individuals):
        #self._save_images(individuals)
        self.conn.root.set_individuals(cPickle.dumps(individuals, 
                                                    constants.PICKLE_PROTOCOL))

    def count_live_individuals(self, where=(), at_time=None):
        return self.conn.root.count_live_individuals(where, at_time)
    
    def count_individuals(self, where=()):
        return self.conn.root.count_individuals(where)
    
    def has_script_input(self):
        return self.conn.root.has_script_input()
    